<template>
  <div class="page">
    <!-- 筛选区域：名称、分类、状态 -->
    <el-form :inline="true" :model="query" class="mb-12">
      <el-form-item label="商品名称">
        <el-input v-model="query.name" placeholder="请输入商品名称" clearable />
      </el-form-item>
      <el-form-item label="分类">
        <!-- 使用树形选择器筛选分类（包含子分类） -->
        <CategoryTreeSelect v-model="query.categoryId" :show-only-enabled="true" placeholder="请选择分类（含子分类筛选）" />
      </el-form-item>
      <el-form-item label="状态">
        <!-- 状态筛选：使用后端枚举值 0草稿/1上架/2下架/3已删除 -->
        <el-select v-model="query.status" placeholder="请选择">
          <el-option label="草稿" :value="0" />
          <el-option label="上架" :value="1" />
          <el-option label="下架" :value="2" />
          <el-option label="已删除" :value="3" />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="onSearch">搜索</el-button>
        <el-button @click="onReset">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 操作区域：新增、批量删除、批量上/下架 -->
    <div class="mb-12">
      <el-button type="primary" @click="openEdit()">新增商品</el-button>
      <el-button type="danger" :disabled="!selection.length" @click="onBatchDelete">批量删除</el-button>
      <el-button :disabled="!selection.length" @click="onBatchChangeStatus('on')">批量上架</el-button>
      <el-button :disabled="!selection.length" @click="onBatchChangeStatus('off')">批量下架</el-button>
    </div>

    <!-- 表格展示：支持选择、分页 -->
    <el-table :data="list" v-loading="loading" @selection-change="selection = $event" border>
      <el-table-column type="selection" width="48" />
      <!-- 商品主图列：如果 mainImageUrl 为空则显示占位图 -->
      <!-- 主图列：使用固定尺寸容器，内部按比例 contain 显示 -->
      <el-table-column label="主图" width="140">
        <template #default="{ row }">
          <!-- 固定 120x160 容器，浅灰背景，内部图片居中并保持比例 -->
          <div class="thumb-box">
            <img
              :src="sanitizeUrl(row.mainImageUrl) || defaultImage"
              class="thumb-contain clickable"
              alt="商品主图"
              role="button"
              @click="openImagePreview(row.mainImageUrl, row.name)"
            />
          </div>
        </template>
      </el-table-column>
      <!-- 名称列：改为可点击文本，点击打开详情弹窗 -->
      <el-table-column label="名称" min-width="160">
        <template #default="{ row }">
          <!-- 使用可点击样式的文本触发详情查看 -->
          <span class="name-link" @click="showDetail(row)" title="查看详情">{{ row.name || '-' }}</span>
        </template>
      </el-table-column>
      <!-- 新品推荐列：根据 isNew 显示是/否标签 -->
      <el-table-column label="新品推荐" width="100">
        <template #default="{ row }">
          <el-tag v-if="row.isNew" type="success" size="small">是</el-tag>
          <el-tag v-else type="info" size="small">否</el-tag>
        </template>
      </el-table-column>
      <!-- 热销推荐列：根据 isHot 显示是/否标签 -->
      <el-table-column label="热销推荐" width="100">
        <template #default="{ row }">
          <el-tag v-if="row.isHot" type="danger" size="small">是</el-tag>
          <el-tag v-else type="info" size="small">否</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="categoryName" label="分类" min-width="160" />
      <el-table-column prop="sellingPrice" label="单价" width="100" />
      <el-table-column prop="stock" label="库存" width="100" />
      <el-table-column prop="statusText" label="状态" width="100" />
      <el-table-column label="操作" width="220">
        <template #default="{ row }">
          <el-button size="small" @click="openEdit(row.id)">编辑</el-button>
          <el-button size="small" type="danger" @click="onDelete(row)">删除</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="mt-12 flex-end">
      <el-pagination
        background
        layout="prev, pager, next, total"
        :total="total"
        :page-size="pageSize"
        :current-page="page"
        @current-change="(p)=>{page=p; fetchList()}"
      />
    </div>

    <!-- 编辑弹窗：表单校验（库存不能为负） -->
    <el-dialog v-model="visible" :title="form.id ? '编辑商品' : '新增商品'" width="640px">
      <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
        <el-form-item label="名称" prop="name">
          <el-input v-model="form.name" />
        </el-form-item>
        <el-form-item label="分类" prop="categoryId">
          <!-- 使用级联选择器加载后端分类树：单选、按层级回显路径；支持加载态与清空 -->
          <div v-loading="categoryLoading" style="display:inline-block;width:100%">
            <el-cascader
              v-model="selectedCategoryPath"
              :options="categoryTree"
              :props="cascaderProps"
              :show-all-levels="true"
              :disabled="categoryLoading"
              clearable
              placeholder="请选择商品所属分类"
              @change="onCategoryChange"
            />
          </div>
        </el-form-item>
        <el-form-item label="单价" prop="sellingPrice">
          <el-input-number v-model="form.sellingPrice" :min="0" :step="0.01" />
        </el-form-item>
        <el-form-item label="库存" prop="stock">
          <el-input-number v-model="form.stock" :min="0" />
        </el-form-item>
        <!-- SKU 编码（只读显示） -->
        <el-form-item label="SKU编码">
          <el-input v-model="form.skuCode" disabled />
        </el-form-item>
        <!-- 成本价与库存预警值 -->
        <el-form-item label="成本价">
          <el-input-number v-model="form.costPrice" :min="0" :step="0.01" />
        </el-form-item>
        <el-form-item label="库存预警值">
          <el-input-number v-model="form.stockWarnThreshold" :min="0" />
        </el-form-item>
        <!-- 品牌ID（只读显示） -->
        <el-form-item label="品牌ID">
          <el-input v-model="form.brandId" disabled />
        </el-form-item>
        <!-- 主图上传：使用自定义上传函数，回显至 form.mainImageUrl -->
        <el-form-item label="主图上传">
          <el-upload
            list-type="picture-card"
            :limit="1"
            accept="image/*"
            :file-list="mainImageFileList"
            :http-request="uploadMainImage"
            :on-remove="onMainRemove"
            :on-exceed="() => ElMessage.warning('主图最多上传 1 张')"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>
        </el-form-item>
        <!-- 详情图上传：支持多图，回显至 form.detailImageUrls -->
        <el-form-item label="详情图上传">
          <el-upload
            list-type="picture-card"
            multiple
            accept="image/*"
            :file-list="detailImageFileList"
            :http-request="uploadDetailImage"
            :on-remove="onDetailRemove"
          >
            <el-icon><Plus /></el-icon>
          </el-upload>
        </el-form-item>
        <!-- 主图 URL（只读显示）与预览 -->
        <el-form-item label="主图URL">
          <el-input v-model="form.mainImageUrl" placeholder="主图地址（只读）" disabled />
        </el-form-item>
        <el-form-item label="主图预览">
          <!-- 主图预览：为空时使用占位图 -->
          <img :src="form.mainImageUrl || defaultImage" class="thumb" alt="主图预览" />
        </el-form-item>
        <!-- 详情图片预览（只读） -->
        <el-form-item label="详情图片">
          <div class="detail-images">
            <img v-for="(url, idx) in form.detailImageUrls" :key="idx" :src="url" class="thumb-sm" alt="详情图" />
            <span v-if="!form.detailImageUrls || !form.detailImageUrls.length">暂无详情图片</span>
          </div>
        </el-form-item>
        <el-form-item label="状态" prop="status">
          <!-- 状态枚举：0草稿/1上架/2下架/3已删除 -->
          <el-radio-group v-model="form.status">
            <!-- 按 Element Plus 新 API 使用 value 而非 label，避免弃用警告 -->
            <el-radio :value="0">草稿</el-radio>
            <el-radio :value="1">上架</el-radio>
            <el-radio :value="2">下架</el-radio>
            <el-radio :value="3">已删除</el-radio>
          </el-radio-group>
        </el-form-item>
        <!-- 新品/热销推荐（布尔值） -->
        <el-form-item label="新品推荐">
          <el-switch v-model="form.isNew" :active-value="true" :inactive-value="false" />
        </el-form-item>
        <el-form-item label="热销推荐">
          <el-switch v-model="form.isHot" :active-value="true" :inactive-value="false" />
        </el-form-item>
        <!-- 重量与体积 -->
        <el-form-item label="重量">
          <el-input-number v-model="form.weight" :min="0" :step="0.01" />
        </el-form-item>
        <el-form-item label="体积">
          <el-input-number v-model="form.volume" :min="0" :step="0.01" />
        </el-form-item>
        <el-form-item label="描述">
          <el-input type="textarea" v-model="form.description" />
        </el-form-item>
        <!-- 创建/更新信息与删除标记（只读显示） -->
        <el-form-item label="创建时间">
          <el-input v-model="form.createTime" disabled />
        </el-form-item>
        <el-form-item label="更新时间">
          <el-input v-model="form.updateTime" disabled />
        </el-form-item>
        <el-form-item label="创建人">
          <el-input v-model="form.createBy" disabled />
        </el-form-item>
        <el-form-item label="更新人">
          <el-input v-model="form.updateBy" disabled />
        </el-form-item>
        <el-form-item label="删除标记">
          <el-tag :type="form.isDeleted === 0 ? 'success' : 'danger'">{{ form.isDeleted === 0 ? '未删除' : '已删除' }}</el-tag>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="visible=false">取消</el-button>
        <el-button type="primary" :loading="saving" @click="onSubmit">提交</el-button>
      </template>
    </el-dialog>

    <!-- 商品详情弹窗：分块展示基本信息/价格库存/分类信息 -->
    <el-dialog v-model="detailVisible" title="商品详情" width="720px" append-to-body>
      <!-- 详情加载遮罩：请求中显示加载 -->
      <div v-loading="detailLoading">
        <!-- 基本信息模块 -->
        <h4 class="section-title">基本信息</h4>
        <el-descriptions :column="2" size="small" border>
          <el-descriptions-item label="ID">{{ detailData?.id ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="名称">{{ detailData?.name ?? detailSourceRow?.name ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="SKU编码">{{ detailData?.skuCode ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="描述">{{ detailData?.description ?? '-' }}</el-descriptions-item>
        </el-descriptions>

        <!-- 价格库存模块 -->
        <h4 class="section-title">价格库存</h4>
        <el-descriptions :column="2" size="small" border>
          <el-descriptions-item label="单价">{{ detailData?.sellingPrice ?? detailSourceRow?.sellingPrice ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="成本价">{{ detailData?.costPrice ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="库存">{{ detailData?.stock ?? detailSourceRow?.stock ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="预警值">{{ detailData?.stockWarnThreshold ?? '-' }}</el-descriptions-item>
        </el-descriptions>

        <!-- 分类信息模块 -->
        <h4 class="section-title">分类信息</h4>
        <el-descriptions :column="2" size="small" border>
          <el-descriptions-item label="分类">{{ detailData?.categoryName ?? detailSourceRow?.categoryName ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="分类ID">{{ detailData?.categoryId ?? '-' }}</el-descriptions-item>
          <el-descriptions-item label="状态">{{ detailData?.statusText ?? detailSourceRow?.statusText ?? '-' }}</el-descriptions-item>
        </el-descriptions>
      </div>
      <template #footer>
        <el-button @click="detailVisible=false">关闭</el-button>
      </template>
    </el-dialog>

    <!-- 图片预览弹窗：自适应展示大图，保持比例 -->
    <el-dialog v-model="imagePreviewVisible" :title="imagePreviewTitle" width="70%" append-to-body>
      <div style="text-align:center">
        <!-- 大图展示：为空时仍使用本地占位图；object-fit: contain 保持比例 -->
        <img :src="imagePreviewUrl" class="img-preview" alt="图片预览" />
      </div>
      <template #footer>
        <el-button @click="imagePreviewVisible=false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
// 商品管理页面：包含筛选、分页、增删改查的前端骨架
import { ref, reactive, onMounted, computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
// 引入分类树选择器与工具，支持含子分类筛选
import CategoryTreeSelect from '../components/CategoryTreeSelect.vue'
import { categories, getDescendantIds } from '../store/categories'
// 引入分类 API：编辑时拉取后端分类树
import { getCategoryTree } from '../api/category'
// 引入商品列表接口方法
import { getProductList, getProductDetail, updateProduct } from '../api/product'
// 引入统一 API 客户端，用于文件上传
// 使用商品 API 模块提供的文件上传方法
import { uploadFile } from '../api/product'

// 查询条件
// 查询条件：状态使用数值枚举（0草稿/1上架/2下架/3已删除）
const query = reactive({ name: '', categoryId: null, status: null })
// 列表与分页
const list = ref([])
const selection = ref([])
const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
// 列表加载态：用于显示加载遮罩
const loading = ref(false)
// 主图占位图：当 mainImageUrl 为空时使用
// 本地占位图，避免外网不可达导致图片加载报错
const defaultImage = '/no-image.svg'

// 图片预览状态与方法
// 预览弹窗显示与图片地址、标题
const imagePreviewVisible = ref(false)
const imagePreviewUrl = ref('')
const imagePreviewTitle = ref('图片预览')

// 打开图片预览：传入图片 URL 与可选的商品名称作为标题补充
function openImagePreview(url, name){
  const u = sanitizeUrl(url)
  imagePreviewUrl.value = u || defaultImage
  imagePreviewTitle.value = name ? `图片预览 - ${name}` : '图片预览'
  imagePreviewVisible.value = true
}

// 商品详情弹窗状态与数据
const detailVisible = ref(false)
const detailLoading = ref(false)
// 当前详情数据：优先使用后端详情返回；若失败则回退为列表行数据
const detailData = ref(null)
// 列表行数据用于兜底显示（例如 categoryName 在详情接口可能没有返回）
const detailSourceRow = ref(null)

// 点击名称打开详情：加载后端商品详情并展示
function showDetail(row){
  detailSourceRow.value = row || null
  detailVisible.value = true
  detailLoading.value = true
  const id = row?.id
  if(!id){
    // 无 ID 时直接使用行数据作为详情数据
    detailData.value = row || null
    detailLoading.value = false
    return
  }
  getProductDetail(id).then(res=>{
    if(res && res.code === 200 && res.data){
      detailData.value = res.data
    } else {
      ElMessage.error(res?.message || '获取商品详情失败')
      detailData.value = row || null
    }
  }).catch(()=>{
    ElMessage.error('获取商品详情失败')
    detailData.value = row || null
  }).finally(()=>{
    detailLoading.value = false
  })
}

// 分类树（编辑弹窗用）：后端接口返回，作为 ElCascader 的数据源
const categoryTree = ref([])
// 分类加载态：用于在编辑弹窗中展示加载状态
const categoryLoading = ref(false)
// 级联选择器的选中路径（如 [parentId, id]），用于回显当前分类层级
const selectedCategoryPath = ref([])
// Cascader 配置：映射后端返回的字段名
const cascaderProps = { label: 'name', value: 'id', children: 'children' }

// 在分类树中查找指定分类 ID 的层级路径（返回 ID 数组），用于回显
function findPathById(tree, targetId){
  if(!targetId) return []
  const stack = []
  const dfs = (nodes)=>{
    if(!Array.isArray(nodes)) return false
    for(const n of nodes){
      stack.push(n.id)
      if(n.id === targetId) return true
      if(dfs(n.children)) return true
      stack.pop()
    }
    return false
  }
  return dfs(tree) ? [...stack] : []
}

// 当分类选择变化时，取路径最后一项作为最终分类 ID，写入表单
function onCategoryChange(path){
  form.categoryId = Array.isArray(path) && path.length ? path[path.length-1] : null
  // 触发分类字段校验，确保必填规则生效
  formRef.value?.validateField('categoryId')
}

// 同步回显：当 form.categoryId 与 categoryTree 都就绪时，计算并设置 selectedCategoryPath
function syncSelectedCategoryPath(){
  if(Array.isArray(categoryTree.value) && categoryTree.value.length && form.categoryId){
    selectedCategoryPath.value = findPathById(categoryTree.value, form.categoryId)
  } else {
    selectedCategoryPath.value = []
  }
}

// 编辑弹窗
const visible = ref(false)
const saving = ref(false)
const formRef = ref()
// 表单模型：包含后端返回的所有字段（部分只读显示）
// 状态使用数值枚举（0草稿/1上架/2下架/3已删除）
const form = reactive({
  id: null,
  name: '',
  skuCode: '',
  description: '',
  sellingPrice: 0,
  costPrice: 0,
  stock: 0,
  stockWarnThreshold: 0,
  categoryId: null,
  brandId: null,
  mainImageUrl: null,
  detailImageUrls: [],
  status: 1,
  isNew: false,
  isHot: false,
  weight: null,
  volume: null,
  createTime: '',
  updateTime: '',
  createBy: '',
  updateBy: '',
  isDeleted: 0
})

// 表单校验：库存不能为负，名称必填
const rules = {
  name: [{ required: true, message: '请输入商品名称', trigger: 'blur' }],
  categoryId: [{ required: true, message: '请选择末级分类', trigger: 'change' }],
  sellingPrice: [{ required: true, message: '请输入单价', trigger: 'blur' }],
  stock: [{ validator:(_,v,cb)=> cb(v<0? new Error('库存不能为负'): undefined), trigger: 'change' }],
  status: [{ required: true, message: '请选择状态', trigger: 'change' }]
}

// 上传回显相关：根据表单字段生成上传组件的文件列表（只读展示）
const mainImageFileList = computed(() => {
  return form.mainImageUrl ? [{ name: '主图', url: form.mainImageUrl }] : []
})
const detailImageFileList = computed(() => {
  return Array.isArray(form.detailImageUrls) ? form.detailImageUrls.map((url, idx) => ({ name: `详情图${idx+1}`, url })) : []
})

// 工具方法：清理后端返回的 URL（去掉可能的反引号与空白）
const sanitizeUrl = (u) => String(u || '').replace(/`/g, '').trim()

// 主图上传：调用后端上传接口并回显到表单
// 主图上传：通过 product.js 的 API 调用后端
async function uploadMainImage(option){
  try {
    const res = await uploadFile(option.file)
    if(res && res.code === 200){
      const url = sanitizeUrl(res.data)
      form.mainImageUrl = url
      option.onSuccess?.(res)
    } else {
      option.onError?.(new Error(res?.message || '主图上传失败'))
    }
  } catch (e) {
    option.onError?.(e)
  }
}

// 详情图上传：成功后将 URL 追加到 detailImageUrls
// 详情图上传：通过 product.js 的 API 调用后端
async function uploadDetailImage(option){
  try {
    const res = await uploadFile(option.file)
    if(res && res.code === 200){
      const url = sanitizeUrl(res.data)
      if(!Array.isArray(form.detailImageUrls)) form.detailImageUrls = []
      form.detailImageUrls.push(url)
      option.onSuccess?.(res)
    } else {
      option.onError?.(new Error(res?.message || '详情图上传失败'))
    }
  } catch (e) {
    option.onError?.(e)
  }
}

// 删除主图：清空 mainImageUrl
function onMainRemove(){
  form.mainImageUrl = null
}

// 删除详情图：按 URL 从数组移除
function onDetailRemove(file){
  if(!file?.url) return
  form.detailImageUrls = (form.detailImageUrls || []).filter(u => u !== file.url)
}

// 模拟获取列表（后续可替换为实际 API 调用）
// 改为调用后端接口：GET /api/product/list，提取 data.records
async function fetchList() {
  loading.value = true
  try {
    // 通过 query params 传递筛选与分页参数（后端无需请求体）
    const params = {
      page: page.value,
      pageSize: pageSize.value,
      name: query.name || undefined,
      categoryId: query.categoryId || undefined,
      // 注意：状态为 0 也应传递，因此不能用 ||
      status: query.status != null ? query.status : undefined
    }
    const res = await getProductList(params)
    if (res && res.code === 200 && res.data) {
      const records = Array.isArray(res.data.records) ? res.data.records : []
      // 兼容现有表格列，提供兜底显示值；状态映射遵循后端枚举
      const statusMap = { 0: '草稿', 1: '上架', 2: '下架', 3: '已删除' }
      list.value = records.map(item => ({
        ...item,
        categoryName: item.categoryName ?? '-',
        sellingPrice: item.sellingPrice ?? 0,
        stock: item.stock ?? 0,
        // 显示状态文本：优先枚举映射，其次使用后端给定的 statusText
        statusText: statusMap[item.status] ?? (item.statusText ?? '-')
      }))
      total.value = typeof res.data.total === 'number' ? res.data.total : records.length
    } else {
      ElMessage.error(res?.message || '获取商品列表失败')
      list.value = []
      total.value = 0
    }
  } catch (e) {
    ElMessage.error('获取商品列表失败：请检查网络或服务端')
    list.value = []
    total.value = 0
  } finally {
    loading.value = false
  }
}

function onSearch(){
  page.value = 1
  fetchList()
}
function onReset(){
  query.name = ''
  query.categoryId = null
  // 重置为不筛选状态
  query.status = null
  onSearch()
}

function openEdit(productId){
  // 打开编辑弹窗时，加载分类树供级联选择使用
  categoryLoading.value = true
  getCategoryTree()
    .then(res=>{
      if(res && res.code === 200 && Array.isArray(res.data)){
        categoryTree.value = res.data
        // 分类树到位后尝试同步回显路径
        syncSelectedCategoryPath()
      } else {
        ElMessage.error(res?.message || '分类数据加载失败，请重试')
        categoryTree.value = []
      }
    })
    .catch(()=>{
      ElMessage.error('分类数据加载失败，请重试')
      categoryTree.value = []
    })
    .finally(()=>{
      categoryLoading.value = false
    })
  if(productId){
    // 调用后端获取商品详情接口
    getProductDetail(productId).then(res=>{
      if(res && res.code === 200 && res.data){
        // 将后端返回的状态转换为数值枚举
        const statusNum = typeof res.data.status === 'number' ? res.data.status : Number(res.data.status)
        // 将后端返回的全部字段回显到表单模型
        Object.assign(form, {
          id: res.data.id ?? null,
          name: res.data.name ?? '',
          skuCode: res.data.skuCode ?? '',
          description: res.data.description ?? '',
          sellingPrice: Number(res.data.sellingPrice ?? 0),
          costPrice: Number(res.data.costPrice ?? 0),
          stock: Number(res.data.stock ?? 0),
          stockWarnThreshold: Number(res.data.stockWarnThreshold ?? 0),
          categoryId: res.data.categoryId ?? null,
          brandId: res.data.brandId ?? null,
          mainImageUrl: res.data.mainImageUrl ?? null,
          // 详情图片：后端可能返回 null 或字符串，统一为数组
          detailImageUrls: Array.isArray(res.data.detailImageUrls)
            ? res.data.detailImageUrls
            : (res.data.detailImageUrls ? [res.data.detailImageUrls] : []),
          status: isNaN(statusNum) ? 1 : statusNum,
          isNew: Boolean(res.data.isNew),
          isHot: Boolean(res.data.isHot),
          weight: res.data.weight ?? null,
          volume: res.data.volume ?? null,
          createTime: res.data.createTime ?? '',
          updateTime: res.data.updateTime ?? '',
          createBy: res.data.createBy ?? '',
          updateBy: res.data.updateBy ?? '',
          isDeleted: Number(res.data.isDeleted ?? 0)
        })
      } else {
        ElMessage.error(res?.message || '获取商品详情失败')
        // 失败时回退到完整默认值
        Object.assign(form, {
          id: null,
          name: '',
          skuCode: '',
          description: '',
          sellingPrice: 0,
          costPrice: 0,
          stock: 0,
          stockWarnThreshold: 0,
          categoryId: null,
          brandId: null,
          mainImageUrl: null,
          detailImageUrls: [],
          status: 1,
          isNew: false,
          isHot: false,
          weight: null,
          volume: null,
          createTime: '',
          updateTime: '',
          createBy: '',
          updateBy: '',
          isDeleted: 0
        })
      }
      // 商品详情就绪后，尝试根据已加载的分类树回显路径
      syncSelectedCategoryPath()
      visible.value = true
    })
  } else {
    // 新增场景使用完整默认值
    Object.assign(form, {
      id: null,
      name: '',
      skuCode: '',
      description: '',
      sellingPrice: 0,
      costPrice: 0,
      stock: 0,
      stockWarnThreshold: 0,
      categoryId: null,
      brandId: null,
      mainImageUrl: null,
      detailImageUrls: [],
      status: 1,
      isNew: false,
      isHot: false,
      weight: null,
      volume: null,
      createTime: '',
      updateTime: '',
      createBy: '',
      updateBy: '',
      isDeleted: 0
    })
  }
  // 新增场景：清空级联选中路径
  selectedCategoryPath.value = []
  visible.value = true
}

function onSubmit(){
  formRef.value.validate(async (ok)=>{
    if(!ok) return
    saving.value = true
    try {
      // 组装提交数据：按后端接口要求使用 JSON 格式
      const payload = {
        id: form.id,
        name: form.name,
        skuCode: form.skuCode,
        description: form.description,
        sellingPrice: Number(form.sellingPrice ?? 0),
        costPrice: Number(form.costPrice ?? 0),
        stock: Number(form.stock ?? 0),
        stockWarnThreshold: Number(form.stockWarnThreshold ?? 0),
        categoryId: form.categoryId ?? null,
        brandId: form.brandId ?? null,
        mainImageUrl: form.mainImageUrl || null,
        detailImageUrls: Array.isArray(form.detailImageUrls) ? form.detailImageUrls : [],
        status: Number(form.status ?? 1),
        isNew: !!form.isNew,
        isHot: !!form.isHot,
        weight: form.weight != null ? Number(form.weight) : null,
        volume: form.volume != null ? Number(form.volume) : null
      }
      const res = await updateProduct(payload)
      if(res && res.code === 200){
        ElMessage.success('修改成功')
        visible.value = false
        fetchList()
      } else {
        ElMessage.error(res?.message || '修改失败')
      }
    } catch (e) {
      ElMessage.error('修改失败')
    } finally {
      saving.value = false
    }
  })
}

function onDelete(row){
  ElMessageBox.confirm('确认删除该商品吗？', '提示', { type: 'warning' }).then(()=>{
    // 调用后端删除接口
    ElMessage.success('删除成功（示例）')
    fetchList()
  })
}

function onBatchDelete(){
  ElMessageBox.confirm(`确认删除选中的 ${selection.value.length} 个商品吗？`, '提示', { type: 'warning' }).then(()=>{
    ElMessage.success('批量删除成功（示例）')
    fetchList()
  })
}

function onBatchChangeStatus(status){
  ElMessageBox.confirm(`确认批量${status==='on'?'上架':'下架'}选中商品吗？`, '提示', { type: 'warning' }).then(()=>{
    ElMessage.success('批量状态更新成功（示例）')
    fetchList()
  })
}

onMounted(fetchList)
</script>

<style scoped>
.page { background: #fff; padding: 16px; border: 1px solid #ebeef5; }
.mb-12 { margin-bottom: 12px; }
.mt-12 { margin-top: 12px; }
.flex-end { display: flex; justify-content: flex-end; }
/* 商品主图样式：统一尺寸与圆角，保持与整体风格协调 */
.thumb { width: 72px; height: 72px; object-fit: cover; border-radius: 6px; border: 1px solid #ebeef5; }
/* 缩略图可点击态样式 */
.clickable { cursor: zoom-in; }
/* 详情图片容器与小缩略图样式 */
.detail-images { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.thumb-sm { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; border: 1px solid #ebeef5; }
/* 大图预览：自适应弹窗，保持原图比例与清晰度 */
.img-preview { max-width: 100%; max-height: 70vh; width: auto; height: auto; object-fit: contain; display: inline-block; }
/* 标签间距 */
.mr-6 { margin-right: 6px; }

/* 列表主图：固定容器尺寸，居中 + 浅灰背景，内部图片按比例缩放 */
.thumb-box { width: 120px; height: 160px; background: #f5f7fa; border: 1px solid #ebeef5; border-radius: 6px; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.thumb-contain { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
/* 名称列可点击样式：与 Element Plus 主色协调 */
.name-link { color: #409EFF; cursor: pointer; }
.name-link:hover { text-decoration: underline; }
/* 详情弹窗分块标题样式 */
.section-title { margin: 12px 0 8px; font-weight: 600; color: #303133; }
</style>